﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using BCCommon;
using BCCommon.Enums;
using BCCommon.ExceptionExtensions;
using BCDto.UploadHandleComponent;
using Microsoft.Extensions.Configuration;

namespace BCService.UploadHandleComponent
{
    /// <summary>
    /// 上传文件信息处理服务
    /// </summary>
    public class UploadFileInfoHandleService : IUploadFileInfoHandleService
    {
        private readonly IConfiguration configuration;
        public UploadFileInfoHandleService(IConfiguration configuration)
        {
            this.configuration = configuration;
        }

        #region 获取允许上传文件类型字典
        /// <summary>
        /// 获取允许上传文件类型字典
        /// </summary>
        /// <returns></returns>
        private Dictionary<string, string> GetAllowType()
        {
            //允许上传的类型
            Dictionary<string, string> allowType = new Dictionary<string, string>();
            allowType.Add(".jpg", "image");
            allowType.Add(".jpeg", "image");
            allowType.Add(".gif", "image");
            allowType.Add(".bmp", "image");
            allowType.Add(".png", "image");

            allowType.Add(".doc", "office");
            allowType.Add(".docx", "office");
            allowType.Add(".xls", "office");
            allowType.Add(".xlsx", "office");
            allowType.Add(".csv", "office");
            allowType.Add(".ppt", "office");
            allowType.Add(".pptx", "office");
            allowType.Add(".pub", "office");
            allowType.Add(".txt", "office");
            allowType.Add(".md", "office");
            allowType.Add(".xml", "office");

            allowType.Add(".rar", "office");
            allowType.Add(".zip", "office");
            allowType.Add(".tar", "office");
            allowType.Add(".gz", "office");
            allowType.Add(".7z", "office");
            allowType.Add(".bz2", "office");
            allowType.Add(".cab", "office");
            allowType.Add(".iso", "office");

            allowType.Add(".flv", "video");
            allowType.Add(".swf", "video");
            allowType.Add(".mkv", "video");
            allowType.Add(".avi", "video");
            allowType.Add(".rm", "video");
            allowType.Add(".rmvb", "video");
            allowType.Add(".mpeg", "video");
            allowType.Add(".mpg", "video");
            allowType.Add(".ogg", "video");
            allowType.Add(".ogv", "video");
            allowType.Add(".mov", "video");
            allowType.Add(".wmv", "video");
            allowType.Add(".webm", "video");
            allowType.Add(".mp4", "video");
            allowType.Add(".mp3", "voice");
            allowType.Add(".amr", "voice");
            allowType.Add(".wav", "voice");
            allowType.Add(".wma", "voice");
            allowType.Add(".mid", "voice");

            return allowType;
        }
        #endregion

        /// <summary>
        /// 初始化上传文件信息
        /// </summary>
        /// <param name="fileName">文件名</param>
        /// <param name="usage">文件用途</param>
        /// <param name="fileSuffix">缺少后缀时使用jpg固定后缀</param>
        /// <exception cref="UploadFileException">上传文件类型错误</exception>
        /// <returns></returns>
        public UploadFileDto Init(string fileName, string usage,string fileSuffix)
        {
            if (string.IsNullOrWhiteSpace(fileName))
            {
                throw new ArgumentException("文件名称不能为空");
            }
            if (!fileName.Contains("."))
            {
                throw new ArgumentException("文件名称未包含文件后缀名");
            }
            if (string.IsNullOrWhiteSpace(usage))
            {
                throw new ArgumentException("文件用途不能为空");
            }
            Dictionary<string, string> allowType = GetAllowType();

            UploadFileDto uploadFileDto = new UploadFileDto();
            uploadFileDto.FileSuffix = string.IsNullOrWhiteSpace(Path.GetExtension(fileName))? fileSuffix: Path.GetExtension(fileName).ToLower();      //文件扩展名
            uploadFileDto.ApplicationRootDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).FullName;                         //当前系统根目录
            uploadFileDto.WebsiteRootDirectory = Path.Combine(uploadFileDto.ApplicationRootDirectory, configuration["WebsiteName"]);        //当前网站目录
            uploadFileDto.FolderName = allowType[uploadFileDto.FileSuffix];
            uploadFileDto.WebsiteName = uploadFileDto.FolderName!= "office" ? configuration["DefaultHost"] : configuration["CurrentlyImageHost"];
            
            DateTime dateTime = DateTime.Now;
            string datePath = dateTime.Year + "\\" + dateTime.Month + "\\" + dateTime.Day;
            string fileDirectory = Path.Combine(uploadFileDto.FolderName, datePath);                                                        //上传文件目录
            bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
            if (!isWindows)
            {
                fileDirectory = fileDirectory.Replace("\\", "/");
            }
            Random random = new Random();
            int f = random.Next(0, 9999);
            uploadFileDto.FileName = DateTime.Now.ToString("yyyyMMddHHmmssffff") + f;                                                           //新文件记录编号
            uploadFileDto.FullName = string.Format("{0}{1}", uploadFileDto.FileName, uploadFileDto.FileSuffix);                                 //新文件名称
            uploadFileDto.DirectoryPath = Path.Combine(uploadFileDto.WebsiteRootDirectory, fileDirectory);                                      //文件所在目录
            uploadFileDto.FilePath = Path.Combine(uploadFileDto.DirectoryPath, uploadFileDto.FullName);                                         //最终目标文件路径
            uploadFileDto.Src = string.Format("{0}/{1}", fileDirectory.TrimEnd('/'), uploadFileDto.FullName).Replace("\\", "/");                //最终web返回路径
            uploadFileDto.WebsiteFileDirectory = string.Format("{0}/{1}", uploadFileDto.WebsiteName.TrimEnd('/'), fileDirectory).Replace("\\", "/");  //网站文件目录
            uploadFileDto.WebsiteFullName = string.Format("{0}/{1}", uploadFileDto.WebsiteName.TrimEnd('/'), uploadFileDto.Src).Replace("\\", "/");
            uploadFileDto.Type = uploadFileDto.FileSuffix.TrimStart('.');
            if (!Directory.Exists(uploadFileDto.DirectoryPath))
            {
                Directory.CreateDirectory(uploadFileDto.DirectoryPath);
            }
            if (Enum.TryParse(typeof(UploadUsageType), usage, out object value))
            {
                uploadFileDto.Usage = (UploadUsageType)value;
            }
            else
            {
                throw new UploadFileException("上传文件用途不正确。");
            }
            if (!allowType.Any(p => p.Key.Contains(uploadFileDto.FileSuffix)))
            {
                throw new UploadFileException("此文件不允许上传。");
            }
            return uploadFileDto;
        }

        public void ChangeFolderName(UploadFileDto uploadFileDto)
        {
            if (uploadFileDto.Usage == UploadUsageType.WeChat)
            {
                if (uploadFileDto.RemarkType == UploadFileRemarkType.WeChatPermanentThumbnailMaterial
                    || uploadFileDto.RemarkType == UploadFileRemarkType.WeChatTemporaryThumbnailMaterial)
                {
                    uploadFileDto.FolderName = "thumb";
                }
            }
        }
    }
}
